package com.luych.toolbox.automation.service.job;

import com.luych.toolbox.automation.service.constant.Constant;
import com.luych.toolbox.automation.service.dao.AutoSshServerDao;
import com.luych.toolbox.automation.service.entity.AutoSshServer;
import com.luych.toolbox.common.enums.AutoSshServerStatus;
import com.luych.toolbox.common.event.base.service.publisher.WebSocketEventPublisher;
import com.luych.toolbox.common.event.base.service.publisher.WebSocketLetterPublisher;
import com.luych.toolbox.common.event.base.service.publisher.WebSocketNoticePublisher;
import com.luych.toolbox.common.feign.param.gateway.center.WebSocketEvent;
import com.luych.toolbox.common.service.tool.Cmd;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.bus.BusProperties;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.scheduling.quartz.QuartzJobBean;

public class AutoSshServerHealthCheckJob extends QuartzJobBean {
    private static final Logger LOGGER = LoggerFactory.getLogger(AutoSshServerHealthCheckJob.class);

    private final BusProperties busProperties;
    private final ApplicationEventPublisher applicationEventPublisher;
    private final AutoSshServerDao sshServerDao;

    public AutoSshServerHealthCheckJob(BusProperties busProperties,
                                       ApplicationEventPublisher applicationEventPublisher,
                                       AutoSshServerDao sshServerDao) {
        this.busProperties = busProperties;
        this.applicationEventPublisher = applicationEventPublisher;
        this.sshServerDao = sshServerDao;
    }

    @Override
    protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
        String id = context.getJobDetail().getJobDataMap().getString("id");

        WebSocketLetterPublisher letterPublisher = new WebSocketLetterPublisher(busProperties, applicationEventPublisher);
        WebSocketNoticePublisher noticePublisher = new WebSocketNoticePublisher(busProperties, applicationEventPublisher);
        WebSocketEventPublisher eventPublisher = new WebSocketEventPublisher(busProperties, applicationEventPublisher);

        AutoSshServer sshServer = sshServerDao.findById(id).orElseThrow(() ->
                new JobExecutionException(Constant.SSH_SERVER_NOT_FOUND));
        AutoSshServerStatus status;
        String arch = null, osName = null, osVersion = null;
        LOGGER.info("start to check ssh server {} status...", sshServer.getName());
        try {
            arch = Cmd.executeRemote(sshServer.getHost(), sshServer.getPort(), sshServer.getUser(), sshServer.getPass(), "arch");
            String os = Cmd.executeRemote(sshServer.getHost(), sshServer.getPort(), sshServer.getUser(), sshServer.getPass(), "cat /etc/os-release");
            for (String osLine : os.split("\\n")) {
                if (osLine.startsWith("ID=")) {
                    osName = osLine.replace("ID=", "").replace("\"", "").trim();
                }
                if (osLine.startsWith("VERSION_ID=")) {
                    osVersion = osLine.replace("VERSION_ID=", "").replace("\"", "").trim();
                }
            }
            status = AutoSshServerStatus.NORMAL;
            LOGGER.info("ssh server {} connect success", sshServer.getName());
        } catch (Exception e) {
            LOGGER.error("ssh server {} connect error: {}", sshServer.getName(), e.getMessage());
            status = AutoSshServerStatus.ABNORMAL;
        }
        sshServer.setArch(arch);
        sshServer.setOsName(osName);
        sshServer.setOsVersion(osVersion);
        sshServerDao.save(sshServer);

        if (!sshServer.getStatus().equals(status)) {
            String message = "SSH服务器连接状态通知";
            if (sshServer.getStatus() != AutoSshServerStatus.ABNORMAL && status == AutoSshServerStatus.ABNORMAL) {
                String content = "SSH服务器[" + sshServer.getName() + "]连接异常，请注意修复！";
                letterPublisher.error(sshServer.getOwnerId(), message, content);
                noticePublisher.error(sshServer.getOwnerId(), content);
                eventPublisher.send(new WebSocketEvent(WebSocketEvent.Type.AUTO_SSH_SERVER_ABNORMAL, sshServer.getId()));
            } else if (sshServer.getStatus() != AutoSshServerStatus.NORMAL && status == AutoSshServerStatus.NORMAL) {
                String content = "SSH服务器[" + sshServer.getName() + "]连接正常。";
                letterPublisher.success(sshServer.getOwnerId(), message, content);
                noticePublisher.success(sshServer.getOwnerId(), content);
                eventPublisher.send(new WebSocketEvent(WebSocketEvent.Type.AUTO_SSH_SERVER_NORMAL, sshServer.getId()));
            }

            sshServer.setStatus(status);
            sshServerDao.save(sshServer);
        }
    }
}
